#ifndef _BQ76920_H_
#define _BQ76920_H_

#include "main.h"
#include "stdbool.h"
#include "soft_i2c.h"
#include "FreeRTOS.h"
#include "task.h"
#include "BMS_Config.h"
#include "OLED.H"
#define BQ_I2C_ADDR 0x08    //BQ芯片的iic地址，在芯片手册有
#define CRC_KEY 0x07 //CRC校验，通过 “生成多项式” 对数据进行运算，生成固定长度的校验值（这里是 8 位）

//从一个16位数据中提取低字节
#define LOWBYTE(Data) (unsigned char)(0xff&Data)
//从一个16位数据中提取高字节
#define HIGHBYTE(Data) (unsigned char)(0xff&(Data)>>8)

#define BQ_delay(ms)    osDelay(ms)

////唤醒芯片
//#define BQ_TS1_GPIOx GPIOA
//#define BQ_TS1_Pin GPIO_PIN_15

//ALERT
#define BQ_ALERT_GPIOx GPIOB
#define BQ_ALERT_Pin GPIO_PIN_12
#define BQ_ALERT_EXIT_IRQ EXIT15_10_IRQn

#define BQ_CEL_MAX BMA_CELL_MAX     //最大支持几串
#define BQ_TMEP_MAX BMS_TEMP_MAX    //最多几路温度

#define BQ_MALLOC(size)    pvPortMalloc(size)    //开辟内存
#define BQ_FREE(rmem)      vPortFree(rmem)     //释放内存
/***** 下面定义的是BQ寄存器地址******/
#define SYS_STAT 0x00       //系统状态寄存器

#define CELLBAL1  0x01       //电池均衡功能控制寄存器

//系统控制寄存器
#define SYS_CTRL1 0x04
#define SYS_CTRL2 0x05

//电池保护寄存器，用于配置保护阈值
#define PROTECT1  0x06
#define PROTECT2  0x07
#define PROTECT3  0x08

#define OV_TRIP 0x09    //设置过压保护触发阈值
#define UV_TRIP 0x0A    //设置欠压保护阈值
#define CC_CFG 0x0B     //直接设置为0x19

#define OV_THRESH_BASE 0x2008 //过压阈值寄存器
#define UV_THRESH_BASE 0x1000 //欠压阈值寄存器
#define OV_STEP		   0x10   //过压调整步进值
#define UV_STEP		   0x10   //欠压调整步进值

#define TS1_HI_Byte 0x2C //温度寄存器地址
#define TS2_HI_Byte 0x2E

#define CC_HI_BYTE 0x32//电流采样
#define CC_LO_BYTE 0x33

#define BAT_HI_BYTE 0x2A//电压采样,电压采样只在高8位操作 7.5.2

#define ADCGAIN1 				0x50
#define ADCOFFSET 				0x51
#define ADCGAIN2 				0x59

#define ADCGAIN_BASE			365

#define VC1_HI_Byte 0x0C 
#define VC1_LO_Byte 0x0D
//#define VC2_HI_Byte 0x0E
//#define VC2_LO_Byte 0x0F
//#define VC3_HI_Byte 0x10
//#define VC3_LO_Byte 0x11
//#define VC4_HI_Byte 0x12
//#define VC4_LO_Byte 0x13
//#define VC5_HI_Byte 0x14
//#define VC5_LO_Byte 0x15

#define SCD_THRESH_44mV_22mV	0x00
#define SCD_THRESH_67mV_33mV	0x01
#define SCD_THRESH_89mV_44mV	0x02
#define SCD_THRESH_111mV_56mV	0x03
#define SCD_THRESH_133mV_67mV	0x04
#define SCD_TRHESH_155mV_68mV	0x05
#define SCD_THRESH_178mV_89mV	0x06
#define SCD_THRESH_200mV_100mV	0x07

#define OCD_THRESH_17mV_8mV		0x00
#define OCD_THRESH_22mV_11mV	0x01
#define OCD_THRESH_28mV_14mV	0x02
#define OCD_THRESH_33mV_17mV	0x03
#define OCD_THRESH_39mV_19mV	0x04
#define OCD_THRESH_44mV_22mV	0x05
#define OCD_THRESH_50mV_25mV	0x06
#define OCD_THRESH_56mV_28MV	0x07
#define OCD_THRESH_61mV_31mV	0x08
#define OCD_THRESH_67mV_33mV	0x09
#define OCD_THRESH_72mV_36mV	0x0A
#define OCD_THRESH_78mV_39mV	0x0B
#define OCD_THRESH_83mV_42mV	0x0C
#define OCD_THRESH_89mV_44mV	0x0D
#define OCD_THRESH_94mV_47mV	0x0E
#define OCD_THRESH_100mV_50mV	0x0F
//这些时间延时依据在数据手册15页
//放电短路
typedef enum
{
    BQ_SCD_DELAY_50us=0x00,
    BQ_SCD_DELAY_100us,
    BQ_SCD_DELAY_200us,
    BQ_SCD_DELAY_400us,
}BQ_SCDDelayTypedef;

//放电过流
typedef enum
{
    BQ_OCD_DELAY_10ms=0x00,
    BQ_OCD_DELAY_20ms,
    BQ_OCD_DELAY_40ms,
    BQ_OCD_DELAY_80ms,
    BQ_OCD_DELAY_160ms,
    BQ_OCD_DELAY_320ms,
    BQ_OCD_DELAY_640ms,
    BQ_OCD_DELAY_1280ms,
}BQ_OCDDelayTypedef;
//过压
typedef enum
{
    BQ_OV_DELAY_1s=0x00,
    BQ_OV_DELAY_2s=0x01,
    BQ_OV_DELAY_4s=0x02,
    BQ_OV_DELAY_8s=0x03,
}BQ_OVDelayTypedef;
//欠压
typedef enum{
    BQ_UV_DELAY_1s=0x00,
    BQ_UV_DELAY_4s=0x01,
    BQ_UV_DELAY_8s=0x02,
    BQ_UV_DELAY_16s=0x03,
}BQ_UVDelayTypedef;

//充放电枚举
typedef enum
{
    CHG_CONTROL = 0x01,
	DSG_CONTROL = 0x02
}BQ_ControlTypedef;

//充放电状态控制
typedef enum{
    BQ_STATE_ENABLE,
	BQ_STATE_DISABLE
}BQ_StateTypedef;

//电池编号
typedef enum{
    BQ_CELL_INDEX1  = 0x01,
	BQ_CELL_INDEX2  = 0x02,
	BQ_CELL_INDEX3  = 0x04,
	BQ_CELL_INDEX4  = 0x08,
	BQ_CELL_INDEX5  = 0x10,
	BQ_CELL_ALL		= 0x1F,
}BQ_CellIndexTypedef;



//阈值
typedef struct
{
    BQ_SCDDelayTypedef SCDDelay;
    BQ_OCDDelayTypedef OCDDelay;
    BQ_OVDelayTypedef UVDelay;
    BQ_UVDelayTypedef OVDelay;
    uint16_t UVPThreshold;//欠压保护阈值
    uint16_t OVPThreshold;//过压保护阈值
}BQ_ConfigDataTypedef;

/***电池组参数结构体*****/
typedef struct
{
    float CellVoltage[5];//单节电池电压数组
    float TsxTemperatrue[5];//热敏电阻温度；
    float BatteryCurrent;//电池包总电流
    float BatteryVoltage;//电池包总电压
    //float BatteryPercentage;
}BQ_SampleDataTypedef;
extern BQ_SampleDataTypedef BQ_SampleData;

/*BQ寄存器组*/
     //标志位,用：而不是=是因为：用于位域定义，指定成员占用的比特数，目的是节省内存空间或匹配硬件寄存器的位布局
    //这段代码通过位域将一个字节（uint8_t）拆分成 8 个独立的标志位（OCD、SCD 等），
    //每个标志位对应硬件寄存器中的一个特定功能（如过流检测、短路检测等 
    //: 是位域语法的一部分，用于定义结构体成员占用的比特数
typedef struct _Register_Group
{
	union
	{
		struct
		{
			uint8_t OCD				:1;//放电过流
			uint8_t SCD				:1;//放电短路
			uint8_t OV				:1;//过压
			uint8_t UV				:1;//欠压
			uint8_t OVRD_ALERT		:1;
			uint8_t DEVICE_XREADY	:1;
			uint8_t WAKE			:1;
			uint8_t CC_READY		:1;//ADC读取准备，250MS一次
		}StatusBit;
		uint8_t StatusByte;
	}SysStatus;

	union
	{
		struct
		{
			uint8_t RSVD		:3;
			uint8_t CB5			:1;
			uint8_t CB4			:1;
			uint8_t CB3			:1;
			uint8_t CB2			:1;
			uint8_t CB1			:1;
		}CellBal1Bit;
		uint8_t CellBal1Byte;
	}CellBal1;

	union
	{
		struct
		{
			uint8_t RSVD		:3;
			uint8_t CB10		:1;
			uint8_t CB9			:1;
			uint8_t CB8			:1;
			uint8_t CB7			:1;
			uint8_t CB6			:1;
		}CellBal2Bit;
		uint8_t CellBal2Byte;
	}CellBal2;

	union
	{
		struct
		{
			uint8_t RSVD			:3;
			uint8_t CB15			:1;
			uint8_t CB14			:1;
			uint8_t CB13			:1;
			uint8_t CB12			:1;
			uint8_t CB11			:1;
		}CellBal3Bit;
		uint8_t CellBal3Byte;
	}CellBal3;

	union
	{//系统控制寄存器1标志位
		struct
		{
			uint8_t SHUT_B			:1;//关闭信号B
			uint8_t SHUT_A			:1;//关闭信号A
			uint8_t RSVD1			:1;//保留位
			uint8_t TEMP_SEL		:1;//温度选择位
			uint8_t ADC_EN			:1;//ADC使能位
			uint8_t RSVD2			:2;//保留位
			uint8_t LOAD_PRESENT	:1;//负载存在标志
		}SysCtrl1Bit;
		uint8_t SysCtrl1Byte;
	}SysCtrl1;

	union
	{//系统控制寄存器2标志位
		struct
		{
			uint8_t CHG_ON			:1;//充电
			uint8_t DSG_ON			:1;//放电
			uint8_t WAKE_T			:2;
			uint8_t WAKE_EN			:1;
			uint8_t CC_ONESHOT		:1;//ADC读取寄存器配置
			uint8_t CC_EN			:1;//ADC读取
			uint8_t DELAY_DIS		:1;
		}SysCtrl2Bit;
		uint8_t SysCtrl2Byte;
	}SysCtrl2;

	union
	{
		struct
		{
			uint8_t SCD_THRESH		:3;
			uint8_t SCD_DELAY		:2;
			uint8_t RSVD			:2;
			uint8_t RSNS			:1;
		}Protect1Bit;
		uint8_t Protect1Byte;
	}Protect1;

	union
	{
		struct
		{
			uint8_t OCD_THRESH		:4;
			uint8_t OCD_DELAY		:3;
			uint8_t RSVD			:1;
		}Protect2Bit;
		uint8_t Protect2Byte;
	}Protect2;

	union
	{
		struct
		{
			uint8_t RSVD			:4;
			uint8_t OV_DELAY		:2;
			uint8_t UV_DELAY		:2;
		}Protect3Bit;
		uint8_t Protect3Byte;
	}Protect3;

	uint8_t OVTrip;
	uint8_t UVTrip;
	uint8_t CCCfg;			//must be 0x19

	union
	{
		struct
		{
			uint8_t VC1_HI;
			uint8_t VC1_LO;
		}VCell1Byte;
		uint16_t VCell1Word;
	}VCell1;

	union
	{
		struct
		{
			uint8_t VC2_HI;
			uint8_t VC2_LO;
		}VCell2Byte;
		uint16_t VCell2Word;
	}VCell2;

	union
	{
		struct
		{
			uint8_t VC3_HI;
			uint8_t VC3_LO;
		}VCell3Byte;
		uint16_t VCell3Word;
	}VCell3;

	union
	{
		struct
		{
			uint8_t VC4_HI;
			uint8_t VC4_LO;
		}VCell4Byte;
		uint16_t VCell4Word;
	}VCell4;

	union
	{
		struct
		{
			uint8_t VC5_HI;
			uint8_t VC5_LO;
		}VCell5Byte;
		uint16_t VCell5Word;
	}VCell5;

//	union
//	{
//		struct
//		{
//			uint8_t VC6_HI;
//			uint8_t VC6_LO;
//		}VCell6Byte;
//		uint16_t VCell6Word;
//	}VCell6;

//	union
//	{
//		struct
//		{
//			uint8_t VC7_HI;
//			uint8_t VC7_LO;
//		}VCell7Byte;
//		uint16_t VCell7Word;
//	}VCell7;

//	union
//	{
//		struct
//		{
//			uint8_t VC8_HI;
//			uint8_t VC8_LO;
//		}VCell8Byte;
//		uint16_t VCell8Word;
//	}VCell8;

//	union
//	{
//		struct
//		{
//			uint8_t VC9_HI;
//			uint8_t VC9_LO;
//		}VCell9Byte;
//		uint16_t VCell9Word;
//	}VCell9;

//	union
//	{
//		struct
//		{
//			uint8_t VC10_HI;
//			uint8_t VC10_LO;
//		}VCell10Byte;
//		uint16_t VCell10Word;
//	}VCell10;

//	union
//	{
//		struct
//		{
//			uint8_t VC11_HI;
//			uint8_t VC11_LO;
//		}VCell11Byte;
//		uint16_t VCell11Word;
//	}VCell11;

//	union
//	{
//		struct
//		{
//			uint8_t VC12_HI;
//			uint8_t VC12_LO;
//		}VCell12Byte;
//		uint16_t VCell12Word;
//	}VCell12;

//	union
//	{
//		struct
//		{
//			uint8_t VC13_HI;
//			uint8_t VC13_LO;
//		}VCell13Byte;
//		uint16_t VCell13Word;
//	}VCell13;

//	union
//	{
//		struct
//		{
//			uint8_t VC14_HI;
//			uint8_t VC14_LO;
//		}VCell14Byte;
//		uint16_t VCell14Word;
//	}VCell14;

//	union
//	{
//		struct
//		{
//			uint8_t VC15_HI;
//			uint8_t VC15_LO;
//		}VCell15Byte;
//		uint16_t VCell15Word;
//	}VCell15;

	union
	{
		struct
		{
			uint8_t BAT_HI;
			uint8_t BAT_LO;
		}VBatByte;
		uint16_t VBatWord;
	}VBat;

	union
	{
		struct
		{
			uint8_t TS1_HI;
			uint8_t TS1_LO;
		}TS1Byte;
		uint16_t TS1Word;
	}TS1;

	union
	{
		struct
		{
			uint8_t TS2_HI;
			uint8_t TS2_LO;
		}TS2Byte;
		uint16_t TS2Word;
	}TS2;

	union
	{
		struct
		{
			uint8_t TS3_HI;
			uint8_t TS3_LO;
		}TS3Byte;
		uint16_t TS3Word;
	}TS3;

	union
	{
		struct
		{
			uint8_t CC_HI;
			uint8_t CC_LO;
		}CCByte;
		uint16_t CCWord;
	}CC;

	union
	{
		struct
		{
			uint8_t RSVD1			:2;
			uint8_t ADCGAIN_4_3		:2;
			uint8_t RSVD2			:4;
		}ADCGain1Bit;
		uint8_t ADCGain1Byte;
	}ADCGain1;

	uint8_t ADCOffset;

	union
	{
		struct
		{
			uint8_t RSVD			:5;
			uint8_t ADCGAIN_2_0		:3;
		}ADCGain2Bit;
		uint8_t ADCGain2Byte;
	}ADCGain2;

}RegisterGroup;

void BQ_Init(void);
void BQ_singal_Volt(void);
void BQ_Elec_Collet(void);
void BMS_DataInit(void);
void BQ_Batvolt_Collet(void);
void BQ_Temper_Collect(void);
bool BQ769X0_WriteRegisterByteWithCRC(uint8_t Register,uint8_t data);
bool BQ769X0_ReadRegisterByteWithCRC(uint8_t Register, uint8_t *data);
void BQ_ControlDSGOrCHG(BQ_ControlTypedef ControlType,BQ_StateTypedef NewState);
#endif
